package com.enhinck.dbutilweb.controller;

import com.enhinck.dbutilweb.common.WebResponse;
import com.enhinck.dbutilweb.common.database.ConnectionWrapper;
import com.enhinck.dbutilweb.common.database.DbPoolUtil;
import com.enhinck.dbutilweb.common.database.MysqlDBUtil;
import com.enhinck.dbutilweb.common.entity.ExcelFile;
import com.enhinck.dbutilweb.common.entity.InformationSchemaColumns;
import com.enhinck.dbutilweb.common.entity.InformationSchemaTables;
import com.enhinck.dbutilweb.common.entity.OneVersionModifySummary;
import com.enhinck.dbutilweb.common.excel.FieldTypeEnum;
import com.enhinck.dbutilweb.common.excel.JavaDefineEntity;
import com.enhinck.dbutilweb.common.excel.JavaFieldEntity;
import com.enhinck.dbutilweb.common.freemark.mybatisplus.DOFactory;
import com.enhinck.dbutilweb.common.freemark.mybatisplus.VOFactory;
import com.enhinck.dbutilweb.common.main.MysqlDbCompare;
import com.enhinck.dbutilweb.common.main.MysqlDbToDictionary;
import com.enhinck.dbutilweb.common.util.MysqlDbUtil;
import com.enhinck.dbutilweb.common.util.SqlUtil;
import com.enhinck.dbutilweb.common.word.CommonWordWriteUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigInteger;
import java.sql.Connection;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 代码生成
 *
 * @author enhinck Generate auto created
 * @date 2021-03-03 10:52:04
 */
@Slf4j
@Api(description = "代码生成", tags = {"CodeGenController"})
@RestController
@AllArgsConstructor
public class CodeGenController {
    private final DbPoolUtil dbPoolUtil;
    private final MysqlDBUtil mysqlDBUtil;

    /**
     * 数据库表列表
     *
     * @return
     */
    @ApiOperation("数据库表列表")
    @GetMapping("/codeGen/do")
    public void codeDO(@RequestParam("id") Long id, @RequestParam(value = "tableName", required = false) String tableName,HttpServletResponse response) {
        ConnectionWrapper connectionWrapper = null;
        try {
            connectionWrapper = dbPoolUtil.getConnection(id);
            Connection connection = connectionWrapper.getConnection();
            Map<String, InformationSchemaColumns> tableColumns = MysqlDbUtil.getColumnsByTableName(tableName, connection);
            List<InformationSchemaTables> informationSchemaTables = MysqlDbUtil.getTables(connection, tableName);

            connectionWrapper.setLastQueryTime(System.currentTimeMillis());
            InformationSchemaTables informationSchemaTable = informationSchemaTables.get(0);
            String describe = informationSchemaTable.getTableComment();
            JavaDefineEntity javaDefineEntity = new JavaDefineEntity();
            javaDefineEntity.setTableName(tableName);
            javaDefineEntity.setDescribe(describe);
            String javaName = SqlUtil.toJavaName(tableName);
            javaDefineEntity.setJavaName(javaName);

            tableColumns.forEach((key, tableColumn) -> {
                JavaFieldEntity javaFieldEntity = new JavaFieldEntity();
                javaFieldEntity.setName(tableColumn.getColumnName());
                javaFieldEntity.setDescribe(tableColumn.getColumnComment());
                String columnType = tableColumn.getColumnType();
                if (columnType.toLowerCase().contains("text")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                    javaFieldEntity.setLength(BigInteger.valueOf(1000L));
                } else if (columnType.toLowerCase().contains("varchar")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else if (columnType.toLowerCase().contains("datetime")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.DATE);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else if (columnType.toLowerCase().contains("bigint")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.LONG);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else if (columnType.toLowerCase().contains("int")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.INTEGER);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else {
                    javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                }
                javaDefineEntity.addField(javaFieldEntity);
            });

            WebFreemarkUtil.write(DOFactory.getInstance().create(javaDefineEntity),response);
        } catch (Exception e) {
            log.error("{}", e);
        } finally {
            dbPoolUtil.release(connectionWrapper);
        }
    }


    /**
     * 数据库表列表
     *
     * @return
     */
    @ApiOperation("数据库表列表")
    @GetMapping("/codeGen/vo")
    public void codeVO(@RequestParam("id") Long id, @RequestParam(value = "tableName", required = false) String tableName,HttpServletResponse response) {
        ConnectionWrapper connectionWrapper = null;
        try {
            connectionWrapper = dbPoolUtil.getConnection(id);
            Connection connection = connectionWrapper.getConnection();
            Map<String, InformationSchemaColumns> tableColumns = MysqlDbUtil.getColumnsByTableName(tableName, connection);
            List<InformationSchemaTables> informationSchemaTables = MysqlDbUtil.getTables(connection, tableName);
            connectionWrapper.setLastQueryTime(System.currentTimeMillis());
            InformationSchemaTables informationSchemaTable = informationSchemaTables.get(0);
            String describe = informationSchemaTable.getTableComment();
            JavaDefineEntity javaDefineEntity = new JavaDefineEntity();
            javaDefineEntity.setTableName(tableName);
            javaDefineEntity.setDescribe(describe);
            String javaName = SqlUtil.toJavaName(tableName);
            javaDefineEntity.setJavaName(javaName);

            tableColumns.forEach((key, tableColumn) -> {
                JavaFieldEntity javaFieldEntity = new JavaFieldEntity();
                javaFieldEntity.setName(tableColumn.getColumnName());
                javaFieldEntity.setDescribe(tableColumn.getColumnComment());
                String columnType = tableColumn.getColumnType();
                if (columnType.toLowerCase().contains("text")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                    javaFieldEntity.setLength(BigInteger.valueOf(1000L));
                } else if (columnType.toLowerCase().contains("varchar")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else if (columnType.toLowerCase().contains("datetime")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.DATE);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else if (columnType.toLowerCase().contains("bigint")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.LONG);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else if (columnType.toLowerCase().contains("int")) {
                    javaFieldEntity.setFieldType(FieldTypeEnum.INTEGER);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                } else {
                    javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                    javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                }
                javaDefineEntity.addField(javaFieldEntity);
            });

            WebFreemarkUtil.write(VOFactory.getInstance().create(javaDefineEntity),response);
        } catch (Exception e) {
            log.error("{}", e);
        } finally {
            dbPoolUtil.release(connectionWrapper);
        }
    }


    @ApiOperation("数据库表列表")
    @GetMapping("/codeGen/common")
    public void codeCommon(@RequestParam("id") Long id, @RequestParam(value = "tableName", required = false) String tableName,@RequestParam(value = "javaClassName", required = false) String javaClassName,@RequestParam(value = "columns", required = false) String columns,HttpServletResponse response) {
        ConnectionWrapper connectionWrapper = null;
        try {
            List<String> columsList = Arrays.asList(columns.split(","));
            Set<String> collect =  columsList.stream().collect(Collectors.toSet());
            connectionWrapper = dbPoolUtil.getConnection(id);
            Connection connection = connectionWrapper.getConnection();
            Map<String, InformationSchemaColumns> tableColumns = MysqlDbUtil.getColumnsByTableName(tableName, connection);
            List<InformationSchemaTables> informationSchemaTables = MysqlDbUtil.getTables(connection, tableName);
            connectionWrapper.setLastQueryTime(System.currentTimeMillis());
            InformationSchemaTables informationSchemaTable = informationSchemaTables.get(0);
            String describe = informationSchemaTable.getTableComment();
            JavaDefineEntity javaDefineEntity = new JavaDefineEntity();
            javaDefineEntity.setTableName(tableName);
            javaDefineEntity.setDescribe(describe);
            String javaName = SqlUtil.toJavaName(tableName);
            javaDefineEntity.setJavaName(javaName);
            tableColumns.forEach((key, tableColumn) -> {
              if ( collect.contains(tableColumn.getColumnName())){
                  JavaFieldEntity javaFieldEntity = new JavaFieldEntity();
                  javaFieldEntity.setName(tableColumn.getColumnName());
                  javaFieldEntity.setDescribe(tableColumn.getColumnComment());
                  String columnType = tableColumn.getColumnType();
                  if (columnType.toLowerCase().contains("text")) {
                      javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                      javaFieldEntity.setLength(BigInteger.valueOf(1000L));
                  } else if (columnType.toLowerCase().contains("varchar")) {
                      javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                      javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                  } else if (columnType.toLowerCase().contains("datetime")) {
                      javaFieldEntity.setFieldType(FieldTypeEnum.DATE);
                      javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                  } else if (columnType.toLowerCase().contains("bigint")) {
                      javaFieldEntity.setFieldType(FieldTypeEnum.LONG);
                      javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                  } else if (columnType.toLowerCase().contains("int")) {
                      javaFieldEntity.setFieldType(FieldTypeEnum.INTEGER);
                      javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                  } else {
                      javaFieldEntity.setFieldType(FieldTypeEnum.STRING);
                      javaFieldEntity.setLength(tableColumn.getCharacterMaximumLength());
                  }
                  javaDefineEntity.addField(javaFieldEntity);
              }
            });

            WebFreemarkUtil.write(VOFactory.getInstance().create(javaDefineEntity,javaClassName),response);
        } catch (Exception e) {
            log.error("{}", e);
        } finally {
            dbPoolUtil.release(connectionWrapper);
        }
    }

}